package com.atguigu.ware.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.atguigu.common.constant.WareConstant;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.ware.dao.PurchaseDao;
import com.atguigu.ware.entity.PurchaseDetailEntity;
import com.atguigu.ware.entity.PurchaseEntity;
import com.atguigu.ware.service.PurchaseDetailService;
import com.atguigu.ware.service.PurchaseService;
import com.atguigu.ware.service.WareSkuService;
import com.atguigu.ware.vo.MergeVO;
import com.atguigu.ware.vo.PurchaseDoneVO;
import com.atguigu.ware.vo.PurchaseItemDoneVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Resource
    PurchaseDetailService detailService;

    @Resource
    WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceive(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new LambdaQueryWrapper<PurchaseEntity>()
                        .eq(PurchaseEntity::getStatus, 0).or()
                        .eq(PurchaseEntity::getStatus, 1)
        );
        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void mergePurchase(MergeVO mergeVO) {
        Long purchaseId = mergeVO.getPurchaseId();
        if (purchaseId == null) {
            PurchaseEntity purchaseEntity = PurchaseEntity.builder().status(WareConstant.PurchaseStatusEnum.CREATED.getStatus()).build();
            save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        Long finalPurchaseId = purchaseId;
        List<PurchaseDetailEntity> purchaseDetailEntities = mergeVO.getItems().stream().map(item -> PurchaseDetailEntity.builder().id(item)
                .purchaseId(finalPurchaseId).status(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getStatus()).build()).collect(Collectors.toList());
        detailService.updateBatchById(purchaseDetailEntities);
    }

    @Override
    public void received(List<Long> ids) {
        //1.确认当前采购单状态
        List<PurchaseEntity> collect = ids.stream().map(item -> {
            PurchaseEntity purchaseEntity = this.getById(item);
            return purchaseEntity;
        }).filter(id ->
                Objects.equals(id.getStatus(), WareConstant.PurchaseStatusEnum.CREATED.getStatus()) ||
                        Objects.equals(id.getStatus(), WareConstant.PurchaseStatusEnum.ASSIGNED.getStatus())
        ).peek(item -> item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getStatus()).setUpdateTime(new Date())
        ).collect(Collectors.toList());
        //2.改变采购单状态
        this.updateBatchById(collect);
        //3.改变采购项目状态
        if (CollUtil.isNotEmpty(collect)) {
            collect.forEach(item -> {
                List<PurchaseDetailEntity> entities = detailService.listDetailByPurchaseId(item.getId());
                List<PurchaseDetailEntity> detailEntities = entities.stream().map(entity -> {
                    PurchaseDetailEntity purchaseDetailEntity = PurchaseDetailEntity.builder().build();
                    purchaseDetailEntity.setId(entity.getId());
                    purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getStatus());
                    return purchaseDetailEntity;
                }).collect(Collectors.toList());
                detailService.updateBatchById(detailEntities);
            });
        }
    }

    @Override
    public void done(PurchaseDoneVO purchaseDoneVO) {
        Long id = purchaseDoneVO.getId();
        //1.改变采购项状态
        boolean flag = true;
        List<PurchaseItemDoneVO> items = purchaseDoneVO.getItems();
        List<PurchaseDetailEntity> updates = new ArrayList<>();
        for (PurchaseItemDoneVO item : items) {
            PurchaseDetailEntity purchaseDetailEntity = PurchaseDetailEntity.builder().build();
            if (Objects.equals(item.getStatus(), WareConstant.PurchaseDetailStatusEnum.HAS_ERROR.getStatus())) {
                flag = false;
                purchaseDetailEntity.setStatus(item.getStatus());
            } else {
                //2.将成功采购的进行入库
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISH.getStatus());
                PurchaseDetailEntity entity = detailService.getById(item.getItemId());
                wareSkuService.addStock(entity.getSkuId(), entity.getWareId(), entity.getSkuNum());
            }
            purchaseDetailEntity.setId(item.getItemId());
            updates.add(purchaseDetailEntity);
        }
        detailService.updateBatchById(updates);
        //3.改变采购单状态
        PurchaseEntity purchaseEntity = PurchaseEntity.builder().build();
        purchaseEntity.setId(id);
        purchaseEntity.setStatus(flag ? WareConstant.PurchaseStatusEnum.FINISH.getStatus() :
                WareConstant.PurchaseStatusEnum.HAS_ERROR.getStatus());
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }
}